import uuid
from django.db import IntegrityError
from BloodSpiderAPI import models
from django import forms
from BloodSpiderAPI.apis.category import utils as category_utils
from BloodSpiderModel.DjangoResponseTool.response_dict import response_dict, get_first_error


# 分类表单
class CategoryForm(forms.ModelForm):
    class Meta:
        model = models.Category
        fields = ['name']
        # uid字段将在视图函数中手动设置


# 创建分类
def create_category(request):
    """创建新的记账分类，需要指定用户ID"""
    if request.method != 'POST':
        return response_dict(message="请使用POST请求", code=1)
    
    # 获取用户ID
    uid = request.POST.get('uid')
    if not uid:
        return response_dict(message="用户ID不能为空", code=1)
    
    # 确保用户ID格式统一，转换为标准UUID格式
    if len(uid) == 32 and '-' not in uid:
        formatted_uid = f"{uid[:8]}-{uid[8:12]}-{uid[12:16]}-{uid[16:20]}-{uid[20:]}"
    else:
        formatted_uid = uid
    
    try:
        # 验证用户是否存在
        user = models.User.objects.get(uid=formatted_uid)
    except models.User.DoesNotExist:
        return response_dict(message="用户不存在", code=1)
    
    form = CategoryForm(request.POST.dict())
    if not form.is_valid():
        return response_dict(data=get_first_error(form), code=1, message="参数错误")
    
    # 获取分类名称
    category_name = request.POST.get('name')
    
    # 检查是否存在同名分类（同一用户下）
    if models.Category.objects.filter(uid=user, name=category_name).exists():
        return response_dict(message="分类名称已存在", code=1)
    
    try:
        category = form.save(commit=False)
        # 手动设置UUID
        category.cid = uuid.uuid4()
        # 设置用户ID
        category.uid = user
        category.save()
        response = category_utils.utils_model_to_dict(category)
        return response_dict(data=response, message="分类创建成功")
    except IntegrityError as e:
        if 'unique constraint' in str(e).lower() or 'unique' in str(e).lower():
            return response_dict(message="分类名称已存在", code=1)
        return response_dict(message=f"创建失败: {str(e)}", code=1)
    except Exception as e:
        return response_dict(message=f"创建失败: {str(e)}", code=1)


# 获取分类列表
def get_category_list(request):
    """获取指定用户的分类列表"""
    if request.method != 'GET':
        return response_dict(message="请使用GET请求", code=1)
    
    # 获取用户ID
    uid = request.GET.get('uid')
    if not uid:
        return response_dict(message="用户ID不能为空", code=1)
    
    # 确保用户ID格式统一，转换为标准UUID格式
    if len(uid) == 32 and '-' not in uid:
        formatted_uid = f"{uid[:8]}-{uid[8:12]}-{uid[12:16]}-{uid[16:20]}-{uid[20:]}"
    else:
        formatted_uid = uid
    
    try:
        # 获取指定用户的分类
        categories = models.Category.objects.filter(uid=formatted_uid)
        category_list = [category_utils.utils_model_to_dict(cat) for cat in categories]
        return response_dict(data=category_list, message="获取成功")
    except Exception as e:
        return response_dict(message=f"获取失败: {str(e)}", code=1)


# 获取分类详情
def get_category_detail(request, cid):
    """获取指定分类的详细信息，确保包含uid信息"""
    if request.method != 'GET':
        return response_dict(message="请使用GET请求", code=1)
    
    try:
        category = models.Category.objects.get(cid=cid)
        response = category_utils.utils_model_to_dict(category)
        return response_dict(data=response, message="获取成功")
    except models.Category.DoesNotExist:
        return response_dict(message="分类不存在", code=1)
    except Exception as e:
        return response_dict(message=f"获取失败: {str(e)}", code=1)


# 更新分类
def update_category(request, cid):
    """更新指定的分类信息，确保只能更新当前用户的分类"""
    if request.method != 'POST':
        return response_dict(message="请使用POST请求", code=1)
    
    try:
        category = models.Category.objects.get(cid=cid)
    except models.Category.DoesNotExist:
        return response_dict(message="分类不存在", code=1)
    
    # 获取用户ID进行验证
    uid = request.POST.get('uid')
    if not uid:
        return response_dict(message="用户ID不能为空", code=1)
    
    # 确保用户ID格式统一，转换为标准UUID格式
    if len(uid) == 32 and '-' not in uid:
        formatted_uid = f"{uid[:8]}-{uid[8:12]}-{uid[12:16]}-{uid[16:20]}-{uid[20:]}"
    else:
        formatted_uid = uid
    
    # 验证用户是否有权限修改该分类
    if str(category.uid.uid) != formatted_uid:
        return response_dict(message="无权限修改该分类", code=1)
    
    # 获取新的分类名称
    new_name = request.POST.get('name')
    
    # 检查是否与同一用户下的其他分类名称冲突
    if new_name and new_name != category.name and models.Category.objects.filter(uid=category.uid, name=new_name).exists():
        return response_dict(message="分类名称已存在", code=1)
    
    form = CategoryForm(request.POST.dict(), instance=category)
    if not form.is_valid():
        return response_dict(data=get_first_error(form), code=1, message="参数错误")
    
    try:
        form.save()
        response = category_utils.utils_model_to_dict(category)
        return response_dict(data=response, message="更新成功")
    except IntegrityError as e:
        if 'unique constraint' in str(e).lower() or 'unique' in str(e).lower():
            return response_dict(message="分类名称已存在", code=1)
        return response_dict(message=f"更新失败: {str(e)}", code=1)
    except Exception as e:
        return response_dict(message=f"更新失败: {str(e)}", code=1)


# 删除分类
def delete_category(request, cid):
    """删除指定的分类，确保只能删除当前用户的分类"""
    if request.method != 'POST':
        return response_dict(message="请使用POST请求", code=1)
    
    # 获取用户ID进行验证
    uid = request.POST.get('uid')
    if not uid:
        return response_dict(message="用户ID不能为空", code=1)
    
    try:
        category = models.Category.objects.get(cid=cid)
        
        # 验证用户是否有权限删除该分类
        # 确保用户ID格式统一，转换为标准UUID格式
        if len(uid) == 32 and '-' not in uid:
            formatted_uid = f"{uid[:8]}-{uid[8:12]}-{uid[12:16]}-{uid[16:20]}-{uid[20:]}"
        else:
            formatted_uid = uid
        
        if str(category.uid.uid) != formatted_uid:
            return response_dict(message="无权限删除该分类", code=1)
        
        category.delete()
        return response_dict(message="删除成功")
    except models.Category.DoesNotExist:
        return response_dict(message="分类不存在", code=1)
    except Exception as e:
        return response_dict(message=f"删除失败: {str(e)}", code=1)